use axum::{ Json,extract::Multipart };
use std::collections::HashMap;
use serde_json::{ json, Value };
use mongodb::{ bson::doc, options::{GridFsUploadOptions, GridFsBucketOptions} };
use futures_util::io::AsyncWriteExt;
use crate::{code, file::utils::{get_file_name, get_file_type}, mdb};
use super::gridfs_download_base64;
// 上传到 gridfs，varchar 32 位
pub async fn upload(mut multipart: Multipart, mul:bool) -> Result<Json<Value>, Json<Value>>{
    let conn = mdb::connect().await?;
    let options = GridFsBucketOptions::builder().build();
    let bucket = conn.gridfs_bucket(options);
    let mut err = String::new();
    let mut up_arr:Vec<HashMap<&str,String>> = Vec::new();
    let mut up_obj:HashMap<&str,String> = HashMap::new();
    //
    while let Some(file) = multipart.next_field().await.unwrap_or_default() {
        let mut result:HashMap<&str,String> = HashMap::new();
        let file_name = file.file_name();          // 文件名
        if file_name.is_none() {
            err = String::from("上传文件名不存在");
            break;
        }
        let file_name = file_name.unwrap();
        let file_name_ = file_name.to_owned();
        
        if mul {
            result.insert("name", file_name.to_owned());
        }else {
            up_obj.insert("name", file_name.to_owned());
        }

        let filename = get_file_name(&file_name);
        let file_type = get_file_type(&file_name);
        
        match file.bytes().await {
            Ok(byte) => {
                // 上传到 gridfs
                let options = GridFsUploadOptions::builder()
                .metadata(doc! { "bucket":"fs", "type": file_type.to_owned(), "temp": true })
                .build();
                // 文件上传
                match bucket.open_upload_stream(&filename).with_options(options).await {
                    Ok(mut u) => {
                        match u.write(&byte).await {
                            Ok(_f) => {
                                u.close().await.unwrap();
                                let bson = u.id();
                                let id = mdb::get_object_id_str(&bson);
                                if let Some(f) = gridfs_download_base64::download(&id, "fs", &file_type,).await? {
                                    if mul {
                                        result.insert("url",f);
                                    }else {
                                        up_obj.insert("url",f);
                                    }
                                }
                                if mul {
                                    result.insert("id",format!("temp/{}.{}", id, &file_type));
                                    up_arr.push(result)
                                }else {
                                    up_obj.insert("id",format!("temp/{}.{}", id, &file_type));
                                }
                            },
                            Err(e) => { 
                                err = e.to_string();
                                break;
                            }
                        };
                    },
                    Err(e) =>{
                        err = e.to_string();
                        break;
                    }
                }
            },
            Err(_) =>{
                err = format!("上传文件【{}】不存在", &file_name_);
                break;
            }
        }
        
    };
    if err.is_empty() {
        if mul {
            code::data(json!(up_arr))
        }else {
            code::data(json!(up_obj))
        }
    }else{
        code::sys(err)
    }
}